第四章 字体和文本

发表于 2018-1-9 09:23:49 | 分类于 CSS |

字体

网页中的字体有三个来源:

  • 用户机器中安装的字体。
  • 保存在第三方网站上的字体。可以使用 link 标签把它们链接到页面上。
  • 保存在 Web 服务器上的字体。这些字体可以使用 @font-face 规则随网页一起发送给浏览器。

与字体样式相关的 6 个属性:

  • font-family
  • font-size
  • font-style
  • font-weight
  • font-variant
  • font(简写属性)

字体与文本

字体是 “文字的不同体式 ”或者 “字的形体结构”。

对于英文而言,每种字体都是由一组具有独特样式的字母、数字和符号组成的。

根据外观,字体可以分为不同的类别(font collection),包括衬线字体(serif)、无衬线字体(sans-serif)和等宽字体(monospace)。

每一类字体可以分成不同的字体族(font family),比如Times 和Helvetica。而字体族中又可以包含不同的字型(font face),反映了相应字体族基本设计的不同变化,例如Times Roman、Times Bold、Helvetica Condensed 和Bodoni italic。

文本就是一组字或字符,比如章标题、段落正文等等,跟使用什么字体无关。

CSS 为字体和文本分别定义了属性。

字体属性主要描述一类字体的大小和外观。比如,使用什么字体族(是Times,还是Helvitica),多大字号,粗体还是斜体。

文本属性描述对文本的处理方式。比如,行高或者字符间距多大,有没有下划线和缩进。

如果想让文字加粗,或者变斜体,可以设定字体属性。而行高和缩进这种只有对文本块(比如标题和段落)才有意义的样式,则要使用文本属性 设定。

字体族

font-family 用于设定元素中的文本使用什么字体。

在指定文本的字体时,需要多列出几种后备字体,以防第一种字体无效。这个字体的列表也叫字体栈。

通用的字体类:

  • serif,也就是衬线字体,在每个字符笔画的末端会有一些装饰线;
  • sans-serif,也就是无衬线字体,字符笔画的末端没有装饰线;
  • monospace,也就是等宽字体,顾名思义,就是每个字符的宽度相等(也称代码体);
  • cursive,也就是草书体或手写体;
  • fantasy,不能归入其他类别的字体(一般都是奇形怪状的字体)。

通用字体类的目的,就是确保在最坏的情况下,文档起码可以通过正确的 字形来显示。

“x 高度”指英文字母不包含(字母 d 和 p 都有的)上伸部分和下伸部分的主要区域,恰好 x 没有这些部分,所以就用它的高度来度量。

字体大小

用于设定字体大小的单位有两种,一种是绝对单位,比如像素或点,另一种是相对单位,比如百分比或 em 。

font-size 是可以继承的。改变一个元素的字体大小,可能会导致其子元 素字体大小成比例地变化。

例如,把 body 元素的 font-size 设定为200%,那么页面中所有元素的文本都会增大一倍。因为浏览器样式表在设定所有元素的字体大小时,使用的都是相对单位 em。比如,h1 被设定为 2em,h2 是 1.5em,p 是 1em。默认情况下,1em 等于 16 像素,这也是 font-size 的基准大小。换算成绝对值,h1 就是 32 像素,h2 是 24 像素,p 是 16 像素。

如果把 body 的字体大小设定为 20px,就是重新设定了基准大小(body 是所有元素的祖先)。因此,h1 会变成 40 像素,h2 会变成 30 像素,而 p 会变成 20 像素。

不过,那些以像素之类的绝对单位重新设定字体大小的元素,不会继承祖先元素的字体大小,它们会按照设定的大小显示。

绝对字体大小

使用像素、派卡(pica)或英寸设定字体大小,它们是绝对单位,因此设定多大就多大,与祖先元素的字体大小无关。使用绝对单位的缺点很明显,那就是在需要调整页面所有元素的字体大小时,必须一个一个地修改样式表中的font-size。

修改 body 元素的字体大小,不会影响页面中以绝对单位控制的元素,但没有设定字体大小的元素则会与 body 的字体大小成比例变化。

设定绝对字体大小时,也可以使用关键字值,比如 x-small、medium、x-large,等等。其中,medium 等于基准大小,其他关键字要么小一点,要么大一点。

相对字体大小

使用百分比、em 或 rem(根元素的字体大小)给某个元素设定了相对字体大小,则该元素的字体大小要相对于最近的 “被设定过字体大小的” 祖先元素来确定。

示例:

<body>
    <p>This is <strong>very important!</strong></p>
</body>
p {font-size:.75em;}
strong {font-size:.75em;}

p 元素的文本为 12 像素(body 的 16 像素基准大小 × 0.75 = 12),折合成点单位是 9 点。

strong 是 p 的子元素,相对大小会逐层复合,strong 的大小应 该是 16 像素 × 0.75 × 0.75 = 9 像素。

改变一个元素的相对字体大小,其子元素的字体大小也会同比例变化。

如果想使用 em,但又需要设定具体的像素大小,可以把 body 的 font-size 设定为 62.5%。这样,就等于把基准大小从 16 像素改为 10 像素(16 × 62.5% = 10)。然后,em 与像素的对应关系就十分明确,1em 等于10 像素,1.5em 等于15 像素,2em 等于20 像素,等等。

rem 单位

CSS3 新增了一个相对单位 rem(root em,根 em)。

这个单位与 em 的区别在于,使用 rem 为元素设定字体大小时,仍然是相对大小,但相对的只是 HTML 根元素。

这个单位可谓集相对大小和绝对大小的优点于一身,通过它既可以做到只修改根元素就成比例地调整所有字体大小,又可以避免字体大小逐层复合的连锁反应。

字体样式

值:italic、oblique、normal。

font-style 设定字体是斜体,还是正体。用 oblique 代替 italic 的结果也一样。

font-style 的作用仅仅是通过 italic 把正体设为斜体,或者通过 normal 把斜体设为正体。

normal 值

font-style 有一个 normal 值,中文就是 “常规” 的意思。 这个值其实不仅 font-style 有,很多其他属性也有,它的作用就是取消所有的特殊样式。

这个值是用来有选择地覆盖某个默认或你设定的全局属性的。

比如,h1 到 h6 默认为粗体,如果想让 h3 以常规字体显示,就需要设定:

h3 {font-weight:normal;}

如果样式表里声明了 a {font-variant:small-caps;} ,那网页中的英文链接都会变成小型大写字母。

要是想让某一组链接仍然以常规的大小写形式显示,可能得另写一个类似这样的声明:

a.speciallink {font-variant:normal;}

英文中的斜体主要表示强调。假如想表示强调,那在 HTML 标记中直接使用 <em> 标签即可,因为它默认就是斜体。

字体粗细

可能的值:100、200……900,或者 lighter、normal、bold 和 bolder 。

(CSS 标准规定的)这些数字值没有什么用,对浏览器来说,它只显示 font-weight 属性的两个值:bold 和 normal 。由于浏览器对数字值的实现各不相同,所以从常规字体到粗体的切换可能发生在不同的数值上——通常是 400 左右。

对于 font-weight 属性来说,最好只用 bold 和 normal 这两个值。

粗体的主要作用是表示重要。实际上,HTML 元素 strong 也表示重要,而它的默认样式就是粗体。

字体变化

值:small-caps、normal。

font-variant 属性除了 normal,就只有一个值,即 small-caps。这个值会导致所有小写英文字母变成小型大写字母。

简写字体属性

font 属性是一个简写形式,通过它只要一条 CSS 声明就可以设定所有字体属性。不过,使用这个简写形式要遵守两条规则,否则浏览器无法正确解释声明的值。

规则一:必须声明 font-size 和 font-family 的值。

规则二:所有值必须按如下顺序声明:

  • font-weight、font-style、font-variant 不分先后;
  • 然后是 font-size;
  • 最后是 font-family。

在设定 font-size 属性的同时,可以顺便设定 line-height(行高)值。也就是说,字体大小和行高的值可以写在一块,比如 12px/1.5 。

文本属性

以下是几个常用用的CSS 文本属性:

  • text-indent
  • letter-spacing
  • word-spacing
  • text-decoration
  • text-align
  • line-height
  • text-transform
  • vertical-align

文本缩进

text-indent 属性设定行内盒子相对于包含元素的起点。默认情况下,这个起点就是包含元素的左上角。

值:长度值(正、负均可)。

给 text-indent 设定正值,文本向右移,得到的是段落首行缩进效果。

给 text-indent 设定一个负值,段落的首行会从包含元素的左侧探出头来。

如果想要这种效果,那么一定得给它留出空间。没有空间,而且在左侧还有其他元素的情况下,探出头来的文本就会挡住那个元素。如果左侧是浏览器窗口,那它就会被切掉。解决这个问题的技巧,就是设定一个比负缩进 值更长的左外边距值。

在设定缩进和外边距时要使用 em,以便在改变字体大小时,它们的长度能够按比例变化。

继承的值与计算的值

text-indent 是可以被子元素继承的。如果在一个 div 上设定了 text-indent 属性,那么 div 中的所有段落都会继承该缩进值。然而,与 所有继承的 CSS 值一样,这个缩进值并不是祖先元素中设定的值,而是计算的值。

假设有一个 400 像素宽的 div,包含的文本缩进 5%,则缩进的距离是 20 像素(400 的 5% )。

在这个 div 中有一个 200 像素宽的段落。作为子元素,它继承父元素的 text-indent 值,所以它包含的文本也缩进。继承的缩进值不是5%,而是 20 像素。也就是说,子元素继承的是根据父元素宽度计算得到的缩进值。

结果,虽然段落只有父元素一半宽,但其中的文本也会缩进 20 像素。这样可以确保无论段落多宽,它们的缩进距离都一样。当然,在子元素 上重新设定 text-indent 属性,可以覆盖继承的值。

文本之“蛇”

CSS 会把元素中的文本放在一个不可见的盒子里,比如对 p 元素中的一段文本,CSS 将其视为很长的一行,在遇到容器边界时会折行。

文本被包含在一个细长的盒子中,这个盒子往往因为折行而断开,分布在多行中。文本盒子跨行时是断开的,只有第一行开头和最后一行末尾是封闭的。

知道这一点,可以更快地实现想要的效果。比如,想缩进段落的第一行,可以使用文本属性 text-indent ,而实际上缩进的是这个文本盒子的起点位置。后续的行是不会缩进的,因为在 CSS 看来,它们就是一个整体。

如果想缩进整个段落,可以使用段落的 margin-left 属性。换句话说,得把整个包含盒子向右移动才行。而永远要记住,文本属性只应用于这个长长的、细细的、内部的文本盒子,而不是包含元素的盒子。

字符间距

用传统排版的术语讲,letter-spacing 控制字距(tracking),也就是文本块中所有字符之间的间距。

letter-spacing 为正值时增大字符间距,为负值时缩小间距。

letter-spacing 对英文字母、汉字及其他字符都起作用。

无论设定字体大小时使用的是什么单位,设定字符间距一定要用相对单位,以便字间距能随字体大小同比例变化。

letter-spacing 的值是在浏览器默认值基础上增加或减少的值。

单词间距

单词间距与字符间距非常相似,区别在于它只调整单词间距,而不影响字符间距,任何长度值(正、负值均可)。。

CSS 把任何两边有空白的字符和字符串都视作“单词”。

文本装饰

text-decoration 属性值包括:underline、overline、line-through、blink、none。

文本对齐

text-align 控制文本在水平方向对齐的方式。

属性有 4 个值,分别是 left、right、center 和 justify。

center 值也可以用来在较大的元素中居中较小的固定宽度的元素或图片。

行高

line-height 属性用于控制文本行之间的间距。

值:任何数字值(不用指定单位)。【疑问:指定单位与不指定单位是有区别的】

CSS 中的行高平均分布在一行文本的上方和下方。举个例子,如果字体大小是 12 像素,行高是 20 像素,则浏览器会在文本上方和下方各加 4 像素的空白,以凑足20像素的行高。

对于类似标题的一行文本来说,line-height 增加的空白就像外边距一样。这一点应该记住,因为有时候即使把外边距和内边距全去掉,标题上下仍然会有空白。如果想把这些空白也去掉,那就只能把文本的行高设定为比字体高度(就是字体大小)还要小,比如设定为小于 1 的值。

文本转换

text-transform 属性用于转换元素中文本的大小写,它可以设定英文文本首字母大写、全部字母大写和全部字母小写。

值:none、uppercase、lowercase、capitalize。

垂直对齐

vertical-align 以基线为参照上下移动文本,但这个属性只影响行内元素。如果想在垂直方向上对齐块级元素,必须把其display 属性设定为inline 。

值:任意长度值以及sub、super、top、middle、bottom 等。

vertical-align 属性最常用于公式或化学分子式中的上标和下标,或者用于文本中脚注的角标,比如把星号变成上角标。

虽然 HTML 标签 <sup><sub> 有默认的上标和下标样式, 但重新设定一下 vertical-align 和 font-size 属性能得到更美观的效果。

web 字体

@font-face 规则可在网页中嵌入可下载字体。

@font-face 规则提供了系统自带字体以外的广泛选择。换句话说,浏览器 可以从Web 服务器下载字体,就意味着不必再依赖用户机器中的字体,而且也可以确保用户能够看到 CSS 中设定的字体。

设定Web 字体的方式有以下三种:

  • 使用 Google Web Fonts 或Adobe 的 Typekit 等公共字体库。
  • 使用事先打好包的 @font-face 包。
  • 使用 Font Squirrel 用自己的字体生成 @font-face 包。

打包的 @font-face 包

在网页中嵌入字体的第二种方式是使用 @font-face 规则,前提是可以从你的网站或第三方 Web 服务器下载到相应的字体。以这种方式提供的字体,会在使用该字体的页面第一次加载时被浏览器下载并缓存起来,以后就不用下载了。但是,除了显示网页之外,用户不能将这种字体用于其他用途。

使用 @font-face 的一个问题是不同浏览器要求的字体格式不一样。

比如,Firefox、Webkit 核心的浏览器(Safari 和 Chrome),以及 iOS 4.1 版之后的移动 Safari 使用 OTF(OpenType)或 TTF(TrueType)字体。Internet Explorer 使用 EOT(Embedded OpenType)。另外, iOS 4.1 之前版本中的移动 Safari 以及其他浏览器使用 SVG(Scalable Vector Graphics)格式。

虽然字体格式不同,但它们往往以现成的字体包的形式存在,或者可以使用本地字体来生成字体包(自己生成字体包首先要获得许可)。

Font Squirrel(http://www.fontsquirrel.com)提供了很多现成的字体包,每个字体包中都包含所有必要格式的字体和为每款浏览器提供正确格式的 CSS 代码。Font Squirrel 还有一个转换程序,能够把你上传的字体转换成字体包。

下面就是 Font Squirrel 为Ubuntu Titling Bold 字体生成的 @font-face 代码。对于其他来源的字体,这种格式也是适用的。

@font-face {
    /*这就是将来在字体栈中引用的字体族的名字*/
    font-family:'UbuntuTitlingBold';
    src: url('UbuntuTitling-Bold-webfont.eot');
    src: url('UbuntuTitling-Bold-webfont.eot?#iefix')
    format('embedded-opentype'),
    url('UbuntuTitling-Bold-webfont.woff')
    format('woff'),
    url('UbuntuTitling-Bold-webfont.ttf')
    format('truetype');
    font-weight: normal;
    font-style: normal;
}

把以上代码添加到网页中之后,就可以使用font-family 以常规方式引用该字体了。 引用字体时要使用 @font-face 规则中 font-family 属性的值作为字体族的名字。

生成 @font-face 包

有时候,可能希望在网页中使用一种特殊字体。

只要获得了把该字体转换 为Web 字体使用的授权,就可以使用 Font Squirrel 的转换程序(http://www.fontsquirrel.com/fontface/generator)把它转换成 @font-face 字体包。

文字版式

文字排版讲求匀称,一般是由看不见的网格,框定页面文字的走向和布局。匀称的版式可以增强页面的可读性。

简单的文本布局

<article>
    <h1>CSS</h1>
    <p>
        CSS stands for Cascading Style Sheets. CSS controls the presentational aspects of your Web pages.
    </p>
    <h2>Block-Level Elements</h2>
    <p>
        Block-level elements stack down the page. They include:
    </p>
    <ul>
        <li><code>header</code></li>
        <li><code>section</code></li>
        <li><code>h1, h2, etc.</code></li>
    </ul>
    <h2>Inline Elements</h2>
    <p>
        Inline elements sit next to each other, if there is room. They include:
    </p>
    <ul>
        <li><code>img</code></li>
        <li><code>a</code></li>
        <li><code>em</code></li>
    </ul>
    <blockquote>
        <q>Typography maketh the Web site.</q>
        <cite>CWS</cite>
    </blockquote>
</article>

下面写一些样式,让版面看起来更舒服。

首先,去掉元素的外边距,设定主字体大小,为包含所有文本元素的 article 应用样式,从视觉上突出它作为容器的角色,然后将它在页面上居中。

/*删除所有元素的外边距*/
* {
    margin:0; 
    padding:0;
}

/*设定主字体族和字体大小*/
body {font:1.0em helvetica, arial, sans-serif;}

/*居中显示盒子*/
article {
    width:500px; 
    margin:20px auto; 
    padding:20px; 
    border:2px solid #999;
}

值为 1.0em 的 font-size 只是显式地声明了默认字体大小,并没有修改什么。但为了将来修改页面中所有文本的字体更方便,必须在 font 简写属性中同时设定字体大小,而且要使用相对单位 em。【后一句不明白,为什么要简写属性同时设定字体大小?为什么要用 em ?body 字体大小用绝对单位,其子元素的继承关系还是可以保持的啊】

接下来,需要巧妙地安排一下元素间的垂直距离。另外,去掉默认外边距后列表项目的符号也跑到了外面,这里一块儿修复。

/*标题周围的空白*/
h1, 
h2, 
h3, 
h4, 
h5, 
h6 {
    line-height:1.15em; 
    margin-bottom:.1em;
}

/*文本元素周围的空白*/
p, 
ul, 
blockquote {
    line-height:1.15em; 
    margin-bottom:.75em;
}

/*缩进列表*/
ul {margin-left:32px;}

把所有元素的行高都缩小了,让它们只比文本稍微高一点点。因为 line-height 会平均分布在文本上下,而只想通过下外边距在每个 元素下方添加空白。但同时,还要留出少量行高,以防段落(和跨行的标题)中相邻的行紧挨上。

为此,这里只设定了两处外边距,而实际的空白要相对于元素的字体大小来计算。

标题的下外边距非常小(等于各自字体大小的 10% ),因此后面的文本会离它很近。文本元素的下外边距大一些(等于各自字体大小的 75% ),以便布局中有较明显的空白。

最后,让各级标题也更均衡一些,保证较大的标题突出,最小的标题也不至于不明显,同时也增大了 code 元素的字体。

/*调整标题文本*/
h1 {font-size:1.9em;}
h2 {font-size:1.6em;}
h3 {font-size:1.4em;}
h4 {font-size:1.2em;}
h5 {font-size:1em;}
h6 {font-size:.9em;}

/*调整段落文本*/
p {font-size:.9em;}

/*调整代码文本(默认值太小了)*/
code {font-size:1.3em;}

基于网络排版

借助网格可以保证布局匀称,同时让页面看起来也很流畅。这里只讨论借助网格创建垂直的文本流。

在下面的例子中,基于垂直的 18 像素网格来规划布局,并让页面中的每一个元素都按网格线对齐。可以临时在 body 元素的背景上添加一张图片,让它为整个页面生成辅助线。

创建一个 100×18 像素的矩形,并在它的底部画了一条灰线。然后将其保存为 .png 格式,把这张图片放到body 元素的背景上:

/*添加网格线*/
body {background-image:url(images/grid_18px.png);}

生成水平的网格背景后,就可以依照网格来定位文本元素了。

这个例子只使用了一些常见的文本元素,但只要理解了背后的原理,写出一个让 HTML 文本元素 “对齐网格” 的样式表一点也不难。而有了这样的样式表,整个网站的布局就有了基础。

这个例子包含如下所示的简单段落:

<p>In traditional typography, text is composed…</p>
/*去掉所有元素的内边距和外边距*/
* {margin:0; padding:0;}

body {

    /*添加网格背景*/
    background-image:url(images/grid_18px.png);

    /*设定字体*/
    font:100% helvetica, arial, sans-serif;

    /*加宽左右外边距,得到一栏的雏形*/
    margin:0 40px 0;
}

p {

    /*设定字体大小*/
    font-size:13px;

    /*将行高设定为等于网格高*/
    line-height:18px;
}

这里把文本的 line-height 设定为网格间的距离(18 像素)。在去掉默认外边距和内边距的情况下,这样就可以确保每一行都相距 18 像素。

再给容器 body 元素添加 4 像素的内边距,以便把元素向下推到文本基线与网格对齐的位置。只要让第一个元素与网格对齐,其他元素就都能对齐了。

这里,给 body 上方添加了 22 像素( 4+18 )的内边距,以便上方能有一定的空间:

body {padding-top:22px;}

给段落添加一条声明:

p {
    /*设定字体大小*/
    font-size:13px;

    /*把行高设定为等于网格高度*/
    line-height:18px;
    margin-bottom:18px;
}

这条声明恰好能在每个段落之间加上一个空行。再加上一段文本,就能更清楚地看这两处修改的效果了。

现在,文本与网格对齐了,段落之间的间距也合适了。接着要设定其他文本元素的字体大小。

首先把 h3 设定为 18 像素,而为了让它恰好在网站中占一行,必须得把它的 line-height 也设定为 18 像素。

为了测试,在两段之间加入一个标签:

<p>In traditional typography, text is composed…</p>
<h3>Type for Every Use</h3>
<p>The ubiquity of type has led typographers…</p>
h3 {
    font-size:18px; 
    line-height:18px;
}

标题的基线比网格低几个像素。然而,下方的段落并没有因此向下挪动相应距离。这是因为标题的 line-height 是正确的,只是由于它现在的字体大小以及字体的因素,导致文本在内部稍微有一点偏移。

纠正这个问题的CSS 如下:

h3 {
    font-size:18px;
    line-height:18px;
    margin-top:-2px;
    margin-bottom:2px;
}

上方的负外边距把文本向上拉,下方同样数量的正外边距用来抵消它,保证后面元素的位置不受影响。

还需要一种类似技巧来对齐比网格高的元素(通常是标题)。

为此,要添加一个 24 像素的 h1 元素。显然,24 像素的文本占据的空间比一行网格要高,因此给它设定的 line-height 是 36 像素,也就是两行网格的高度。然后,就是把 h1 元素放到它应该出现的地方——页面的开头。

<h1>Typography</h1>
<p>In traditional typography…</p>
h1 {
    font-size:24px; 
    line-height:36px;
}

由于line-height 等于两倍网格行高,所以标题没有在网格线上。

这个占两行网格的大标题看起来不太舒服。如果把它移动到下方最近的线上,那么其字母下伸部分就会接触到段落文本,所以把它向上移动。经过一番试错,把它向上移动 13 像素。

另一种思路是把标题文本的基线放在两行网格线之间一半的位置。那会实现一种不同的风格。不过,无论如何都要保证后面的元素与网格对齐。

h1 {
    font-size:24px;
    line-height:36px;
    margin-top:-13px;
    margin-bottom:13px;
}

这样,h1 下方与文本之间就空出了一定距离。对于级别低一点的标题 也可以应用同样的技巧。

在这个练习最后,再加几个不同字体大小的标题、一个无序列表和一个 blockquote 元素。再把网格去掉。

* {
    margin:0; 
    padding:0;
}

body {
    font:100% helvetica, arial, sans-serif; 
    backgroundimage: url(images/grid_18px.png); margin:0 20px 0;
    padding:21px;
}

p {
    font-size:14px; 
    line-height:18px; 
    margin-bottom:18px;
}

h1 {
    font-size:24px; 
    line-height:36px; 
    margin-top:-13px;
    margin-bottom:13px;
}

h2 {
    font-size:18px; 
    line-height:18px; 
    margin-top:-2px;
    margin-bottom:2px;
}

h3 {
    font-size:16px; 
    line-height:18px; 
    margin-top:-2px;
    margin-bottom:2px;
}

ul {margin-bottom:18px;}

li {
    font-size:13px; 
    list-style-type:none; 
    padding:0 20px;
    line-height:18px;
}

a {
    color:#777; 
    text-decoration:none;
}

blockquote {
    font-size:12px; 
    line-height:18px; 
    padding-top:2px; 
    margin-bottom:16px;
}

如果基于网格为一个网站设计了版式,而后将其交给了其他人维护,那这个网站的版式就能始终保持一致,无论页面中包含什么元素,以及以什么顺序包含这些元素。

经典排版练习

<h2>an excerpt from</h2>
<h1>The Hound of the Baskervilles</h1>
<p>
    Holmes stretched out his hand for the manuscript and flattened it upon his knee. &ldquo;You will observe, Watson, the alternative use of the long s and the short. It is one of several indications which enabled me to fix the date.&rdquo; At the head was written: &ldquo;;Baskerville Hall,&rdquo; and below in large, scrawling figures: &ldquo;;1742.&rdquo;
</p>
<p>
    &ldquo;;It appears to be a statement of some sort.&rdquo;
</p>
<p>
    &ldquo;;Yes&mdash;it is a statement of a certain legend which runs in the Baskerville family.&rdquo;
</p>
<blockquote>
    <q>
        Of the origin of the Hound of the Baskervilles there have been many statements, yet as I come in a direct line from Hugo Baskerville, and
        as I had the story from my father&hellip;
    </q>
</blockquote>
<p>
    When Dr. Mortimer had finished reading this singular narrative he pushed his spectacles up on his forehead and stared across at Mr. Sherlock Holmes.
</p>

这段标记包含了几个 HTML 实体,它们代表的是几种标点符号。

HTML 实体引用

在 HTML 标记中,必须把所有和号(&)和小于号(<)都替换成相应的 HTML 实体,也就是 &和 < 。因为 “&” 是实体的第一个字符,而 “<” 是 HTML 标签的第一个字符,它们都有特殊含义。如果不替换的话,浏览器一看到它们就会当成实体和标签来解释后面的内容。

伪元素中添加 HTML 实体,要用其十六进制值。

例如,&#x201C;(左双引号),则需要改写成如下形式:

e::before {content:"\201C";}

就是在数字前面加了一个反斜杠。

设定字体和底层网格

这两段文本使用的主字体是 FontSquirrel 提供的字体 Crimson Roman。把其中的 @font-face 规则添加到了样式表中。之后,就可以在 font-family 属性中引用该字体了。

@font-face {
    font-family:'CrimsonRoman';
    src: url('fonts/Crimson-fontfacekit/Crimson-Roman-webfont.
    eot');

    src: url('fonts/Crimson-fontfacekit/Crimson-Roman-webfont.
    eot?#iefix') format('embedded-opentype'),
        url('fonts/Crimson-fontfacekit/Crimson-Roman-webfont.
    woff') format('woff'),
        url('fonts/Crimson-fontfacekit/Crimson-Roman-webfont.
    ttf') format('truetype'),
        url('fonts/Crimson-fontfacekit/Crimson-Roman-webfont.
    svg#CrimsonRoman') format('svg');

    font-weight: normal;
    font-style: normal;
}

* {margin:0; padding:0;}

body {
    font-family:"CrimsonRoman", georgia, times, serif;
    background-color:#fff;
    margin:0 10% 0;
    background-image:url(grid_24px.png);
}

这里先去掉了所有外边距和内边距,设定了主字体,又添加了左、右外边距,还为对齐文本临时添加了网格。

设计标题

下面从上到下,对齐页面中的每一个元素。第一行的副标题应该与第二行的 主标题形成对比,因为主标题要使用手写字体,所以副标题就设定成间距较宽的小型大写字母。

body {
    font-family:"CrimsonRoman", georgia, times, serif;
    background-color:#fff;
    margin:29px 10% 0;
    background-image:url(grid_24px.png);
}

h2 {
    font-size:18px;
    line-height:24px;
    font-weight:bold;
    text-align:center;
    font-variant:small-caps;
    word-spacing:.5em;
    letter-spacing:.6em;
}

首先,用 font-variant 把副标题转换成小型大写字母,然后应用 word-spacing和 letter-spacing 得到预期结果。

接下来,打开 Google Web Fonts 网站,找到一种名为 Pinyon 的手写体。然后,把 Google Web Fonts 生成的 <link> 标签复制粘贴到 HTML 文档的 <head> 标签里,这样就能在 font-family 声明中引用这种字体了。这里仍然需要用到曾用过的 “负/正外边距” 技巧,把主标题移动到恰好与网格对齐。

<link href='http://fonts.googleapis.com/css?family=Pinyon+Script' rel='stylesheet' type='text/css'>

h1 {
    font-size:60px;
    line-height:96px;
    font-family:"Pinyon Script", cursive;
    margin:4px 0 -4px;
    text-align:center;
    font-weight:normal;
    position:relative;
}

:设计段落和引用

第一段的位置有点高,因此设定它的字体大小、行高。

p {
    font-size:18px; 
    line-height:24px;
}

前三段虽然对齐了,但后面的段落没有,这是因为第三段后面的引用(blockquote)也需要对齐。blockquote 中的文本包含在一个行内元素 q(quote)中,这个元素的默认样式是在文本开头和末尾加上引号。在此,缩进 blockquote,但在其 q 子元素上设定字体大小和行高,因为它才是包含文本的元素:

blockquote {margin:0px 20%;}

q {
    font-size:18px; 
    font-style:italic; 
    line-height:24px;
}

首字下沉效果

给第一段添加一个独特的首字下沉效果。

所谓首字下沉,就是将段落开头的第一个字母变大,然后根据该字母与段落首行的位置关系,又可以分几种不同的风格。在这里,让字母的顶部与段落首行顶部对齐,让字母的底部与段落第三行的基线对齐。

或许以前也见过这种效果,而那些效果中的首字母都被包含在一个 span 元素里。这种做法对于从内容管理系统中动态取文本的网页并不适用。所以,这里要介绍一种不用修改标记的技巧。

为此,需要选择 h1 标题后面第一个段落的第一个字母,而组合使用紧邻同胞选择符 + 和 ::first-letter 伪元素可以做到。选择了第一个字母后,再增大字体并浮动它:

h1 + p::first-letter {
    font-family:times, serif;
    font-size: 90px;
    float:left;
    border:1px solid;
}

首字母增大了,但位置不对。由于实际上是想调整盒子的大小和位置,所以首字母的边框在此可以作为辅助。而边框显示这个盒子只大到了让两行文本绕排,原因是首字母继承了段落的行高和对齐方式。需要设定这个伪元素的 line-height,让它的盒子能包含首字母。

把 line-height 设定为小于 1 的值,以便元素盒子紧紧包住首字母,而不会强迫段落第四行也绕排。

h1 + p::first-letter {
    font-family:times, serif;
    font-size:90px;
    float:left;
    line-height:.65;
    border:1px solid;
}

增大盒子的 line-height 后,第三行也绕排了。现在,只要再给这 个元素顶部添加一点内边距,就可以让字母的底部与段落第三行的基线对齐了。

h1 + p::first-letter {
    font-family:times, serif;
    font-size:-90px;
    float:left; line-height:.65;
    padding:.085em 3px 0 0;
}

这里还添加了 3 像素的右内边距,以便首字母与段落之间空开一点距离。

设计第一行

首字母下沉效果做完了。可是,希望大号首字母到小号正文之间有一个过渡,所以需要把段落第一行的文本变成小型大写字母。

h1 + p::first-line {
    font-variant:small-caps;
    letter-spacing:.15em;
}

使用伪元素而不是额外加标签的好处在于,当行的长度改变时,大 写字母的效果会随之扩展。

最后的修饰

段落之间没有足够的间距,让人很难看出它们的开头在哪里。这里不给段落之间加空白,而是缩进跟在其他段落后面的每一段,作为一组段落起头的一段不缩进。

此外,引用内容两端的引号太难看,所以要在 <q> 标签上应用 ::before 和 ::after 伪元素,插入 Crimson 字体的引号。最后,再从 body

/*只缩进跟在段落后面的段落*/
p + p {text-indent:14px;}

/*引用内容前面的引号*/
q::before {content:"\201C"}

/*引用内容后面的引号*/
q::after {content:"\201D"}

选择要缩进的段落使用的是紧邻同胞选择符,以保证只有段落后面的段落才会缩进。“When Dr. Mortimer...” 开头的那一段,因为前面 是一个 blockquote,不是段落,所以就没有缩进,而且它也十分明显就是一个段落的开头。

使用 ::before 和 ::after 伪元素给引用内容添加引号时使用的是十六进制值。在这里不能给 content 属性设定常规的 HTML 实体,只能使用十六进制实体值,而且只能是改写后的形式。

排版资源

http://ilovetypography.com 在这个网站上,你可以跟着设计师 John Boardley 一起深思,欣赏每一页中别具一格的排版。

http://www.thinkingwithtype.com 这是 Thinking with Type 一书的网站,作者 Ellen Lupton。网站中展示了很多漂亮又经典的版式,还包含一些字体及字体族的信息。

http://webtypography.net 这个站点自称为 The Elements of Typographic Style Applied to the Web—A practical guide to web typography。跟随网站的目录,可以找到各种常用的排版知识和 技巧。